<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\analysis\data\video;

use app\enum\AnalysisEnum;
use app\model\mongo\MongoStatModel;
use app\service\analysis\AnalysisService;
use app\service\analysis\stat\StatVideoService;
use app\service\BaseService;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

final class UserVideoStatService extends BaseService
{
    /**
     * @var int 媒体
     */
    protected int $mediaId = 0;

    /**
     * @var null|StatVideoService 汇总服务
     */
    private ?StatVideoService $service;

    /**
     * @var null|MongoStatModel 汇总模型
     */
    private ?MongoStatModel $object;

    public function __construct(int $mediaId = 0)
    {
        $this->mediaId = $mediaId;
        $this->service = new StatVideoService($this->mediaId);
    }

    /**
     * 是否是日报服务
     */
    public function isService(): bool
    {
        return $this->service->isService();
    }

    /**
     * 获取数据.
     *
     * @return array|Collection|MongoStatModel[]
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getList()
    {
        return $this->service->getAccountAppendList();
    }

    /**
     * 运行汇总.
     *
     * @param MongoStatModel $model 汇总模型
     * @return bool
     */
    public function runTask(MongoStatModel $model): bool
    {
        $this->object = $model;
        if (! $this->object->getKey()) {
            return self::setError('未知汇总数据');
        }

        if (! $this->setStat()) {
            return false;
        }

        return $this->setFinish();
    }

    private function setStat(): bool
    {
        $model = $this->getStatModel();
        $data = [];
        if (! $model->getKey()) {
            $data = [
                'user_id' => $this->object->getAttr('user_id'),
                'video_id' => $this->object->getAttr('video_id'),
                'signature' => $this->object->getAttr('signature'),
            ];
        }
        $data = $this->getStatField($data);
        $model->setAttrs($data);
        if (! $model->save()) {
            return self::setError('保存汇总数据失败');
        }
        return true;
    }

    /**
     * 获取汇总模型.
     * @return mixed
     */
    private function getStatModel()
    {
        $model = AnalysisService::getStatModelList($this->mediaId, AnalysisEnum::TYPE_VIDEO, AnalysisEnum::STAT_KS_USER_VIDEO);
        return $model->where([
            'user_id' => $this->object->getAttr('user_id'),
            'video_id' => $this->object->getAttr('video_id'),
        ])->findOrEmpty();
    }

    /**
     * 获取汇总字段值
     * @param array $data 数据值
     */
    private function getStatField(array $data = []): array
    {
        $map = [
            'user_id' => $this->object->getAttr('user_id'),
            'video_id' => $this->object->getAttr('video_id'),
        ];
        $stat = $this->service->getUserStat($map);
        $data['cost'] = $stat['cost'] ?? 0;
        return $data;
    }

    /**
     * 设置同步完成.
     */
    private function setFinish(): bool
    {
        $this->object->setAttr('is_change', MongoStatModel::IS_CHANGE_USER_APPEND);
        return $this->object->save();
    }
}
